package com.ruoyi.activiti.service.impl;

import com.ruoyi.activiti.controller.ActivitiImageController;
import com.ruoyi.activiti.domain.dto.ActivitiHighLineDTO;
import com.ruoyi.activiti.service.IActivitiHistoryService;
import com.ruoyi.activiti.service.impl.image.CustomProcessDiagramGenerator;
import com.ruoyi.common.utils.StringUtils;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.*;
import org.activiti.engine.*;
import org.activiti.engine.runtime.Execution;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;

@Service
public class ActivitiHistoryServiceImpl implements IActivitiHistoryService {
    protected final Logger log = LoggerFactory.getLogger(ActivitiHistoryServiceImpl.class);
    @Autowired
    private HistoryService historyService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private ProcessEngineConfiguration processEngineConfiguration;
    @Autowired
    private ProcessEngineFactoryBean processEngine;


    @Override
    public ActivitiHighLineDTO gethighLine(String instanceId) {
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(instanceId).singleResult();
        //获取bpmnModel对象
        BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
        //因为我们这里只定义了一个Process 所以获取集合中的第一个即可
        Process process = bpmnModel.getProcesses().get(0);
        //获取所有的FlowElement信息
        Collection<FlowElement> flowElements = process.getFlowElements();

        Map<String, String> map = new HashMap<>();
        for (FlowElement flowElement : flowElements) {
            //判断是否是连线
            if (flowElement instanceof SequenceFlow) {
                SequenceFlow sequenceFlow = (SequenceFlow) flowElement;
                String ref = sequenceFlow.getSourceRef();
                String targetRef = sequenceFlow.getTargetRef();
                map.put(ref + targetRef, sequenceFlow.getId());
            }
        }

        //获取流程实例 历史节点(全部)
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(instanceId)
                .list();
        //各个历史节点   两两组合 key
        Set<String> keyList = new HashSet<>();
        for (HistoricActivityInstance i : list) {
            for (HistoricActivityInstance j : list) {
                if (i != j) {
                    keyList.add(i.getActivityId() + j.getActivityId());
                }
            }
        }
        //高亮连线ID
        Set<String> highLine = new HashSet<>();
        keyList.forEach(s -> highLine.add(map.get(s)));


        //获取流程实例 历史节点（已完成）
        List<HistoricActivityInstance> listFinished = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(instanceId)
                .finished()
                .list();
        //高亮节点ID
        Set<String> highPoint = new HashSet<>();
        listFinished.forEach(s -> highPoint.add(s.getActivityId()));

        //获取流程实例 历史节点（待办节点）
        List<HistoricActivityInstance> listUnFinished = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(instanceId)
                .unfinished()
                .list();

        //需要移除的高亮连线
        Set<String> set = new HashSet<>();
        //待办高亮节点
        Set<String> waitingToDo = new HashSet<>();
        listUnFinished.forEach(s -> {
            waitingToDo.add(s.getActivityId());

            for (FlowElement flowElement : flowElements) {
                //判断是否是 用户节点
                if (flowElement instanceof UserTask) {
                    UserTask userTask = (UserTask) flowElement;

                    if (userTask.getId().equals(s.getActivityId())) {
                        List<SequenceFlow> outgoingFlows = userTask.getOutgoingFlows();
                        //因为 高亮连线查询的是所有节点  两两组合 把待办 之后  往外发出的连线 也包含进去了  所以要把高亮待办节点 之后 即出的连线去掉
                        if (outgoingFlows != null && outgoingFlows.size() > 0) {
                            outgoingFlows.forEach(a -> {
                                if (a.getSourceRef().equals(s.getActivityId())) {
                                    set.add(a.getId());
                                }
                            });
                        }
                    }
                }
            }
        });

        highLine.removeAll(set);
        Set<String> iDo = new HashSet<>(); //存放 高亮 我的办理节点
        //当前用户已完成的任务
        List<HistoricTaskInstance> taskInstanceList = historyService.createHistoricTaskInstanceQuery()
//                    .taskAssignee(SecurityUtils.getUsername())
                .finished()
                .processInstanceId(instanceId).list();

        taskInstanceList.forEach(a -> iDo.add(a.getTaskDefinitionKey()));

        ActivitiHighLineDTO activitiHighLineDTO =new ActivitiHighLineDTO();
        activitiHighLineDTO.setHighPoint(highPoint);
        activitiHighLineDTO.setHighLine(highLine);
        activitiHighLineDTO.setWaitingToDo(waitingToDo);
        activitiHighLineDTO.setiDo(iDo);

        return activitiHighLineDTO;
    }

    @Override
    public String getProcessImage(String procinstId) {
        /*BufferedImage img = new BufferedImage(300, 150, BufferedImage.TYPE_INT_RGB);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        String imgBase64Str = "";
        try {
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(procinstId).singleResult();
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                    .processDefinitionId(historicProcessInstance.getProcessDefinitionId())//使用部署对象ID查询
                    .singleResult();
            List<org.activiti.engine.task.Task> activeTasks=taskService.createTaskQuery().processDefinitionId(processDefinition.getId()).list();
            // 已执行的节点ID集合
            List<String> executedActivityIdList = new ArrayList<String>();
            List<String> highLines = new ArrayList<String>();
            List<String> highNodes = new ArrayList<String>();

            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
            for(org.activiti.engine.task.Task tk:activeTasks){
                executedActivityIdList.add(tk.getTaskDefinitionKey());
                highLines.addAll(getHighLines(bpmnModel,tk.getTaskDefinitionKey()));
                highNodes.addAll(getHighNodes(bpmnModel,tk.getTaskDefinitionKey()));
            }
            // 获取流程图图像字符流
            InputStream imageStream = new DefaultProcessDiagramGenerator().generateDiagram(bpmnModel, "png",
                    highNodes, highLines, "宋体", "宋体", "宋体", null, 1.0);
            // 输出资源内容到相应对象
            byte[] b = new byte[1024];
            int len;
            while ((len = imageStream.read(b, 0, 1024)) != -1) {
                outputStream.write(b, 0, len);
            }
            imgBase64Str = "data:image/png;base64," + Base64.getEncoder().encodeToString(Objects.requireNonNull(outputStream.toByteArray()));
            imageStream.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return imgBase64Str;*/
        return "";
    }

    @Override
    public String gethighLine2(String instanceId) {
        ActivitiHighLineDTO activitiHighLineDTO = this.gethighLine(instanceId);

        ProcessDiagramGenerator processDiagramGenerator = null;
        // 使用默认的程序图片生成器
        processDiagramGenerator = new DefaultProcessDiagramGenerator();
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(instanceId).singleResult();
        //获取bpmnModel对象
        BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
        //因为我们这里只定义了一个Process 所以获取集合中的第一个即可
        Process process = bpmnModel.getProcesses().get(0);
        //获取所有的FlowElement信息
        Collection<FlowElement> flowElements = process.getFlowElements();


        // 高亮流程已发生流转的线id集合
        List<String> highLightedFlowIds = new ArrayList<>();
        highLightedFlowIds.addAll(activitiHighLineDTO.getHighLine());

        List<String> highLightedActivitiIds = new ArrayList<>();
        highLightedActivitiIds.addAll(activitiHighLineDTO.getHighPoint());
        // 使用默认配置获得流程图表生成器，并生成追踪图片字符流
        InputStream imageStream = processDiagramGenerator.generateDiagram(bpmnModel,
                highLightedActivitiIds, highLightedFlowIds, "宋体",
                "微软雅黑", "黑体");
        String imgBase64Str = "";
        // 输出图片内容
        try {
            BufferedImage img = new BufferedImage(300, 150, BufferedImage.TYPE_INT_RGB);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            // 输出资源内容到相应对象
            byte[] b = new byte[1024];
            int len;
            while ((len = imageStream.read(b, 0, 1024)) != -1) {
                outputStream.write(b, 0, len);
            }
            imgBase64Str = "data:image/png;base64," + Base64.getEncoder().encodeToString(Objects.requireNonNull(outputStream.toByteArray()));
            imageStream.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return imgBase64Str;
    }

    @Override
    public void gethighLine3(String instanceId, HttpServletResponse response) {
        ActivitiHighLineDTO activitiHighLineDTO = this.gethighLine(instanceId);

        ProcessDiagramGenerator processDiagramGenerator = null;
        // 使用默认的程序图片生成器
        processDiagramGenerator = new DefaultProcessDiagramGenerator();
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(instanceId).singleResult();
        //获取bpmnModel对象
        BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
        //因为我们这里只定义了一个Process 所以获取集合中的第一个即可
        Process process = bpmnModel.getProcesses().get(0);
        //获取所有的FlowElement信息
        Collection<FlowElement> flowElements = process.getFlowElements();


        // 高亮流程已发生流转的线id集合
        List<String> highLightedFlowIds = new ArrayList<>();
        highLightedFlowIds.addAll(activitiHighLineDTO.getHighLine());

        List<String> highLightedActivitiIds = new ArrayList<>();
        highLightedActivitiIds.addAll(activitiHighLineDTO.getHighPoint());
        // 使用默认配置获得流程图表生成器，并生成追踪图片字符流
        InputStream imageStream = processDiagramGenerator.generateDiagram(bpmnModel,
                highLightedActivitiIds, highLightedFlowIds, "宋体",
                "微软雅黑", "黑体");
        String imgBase64Str = "";
        // 输出图片内容
        try {
            // 输出资源内容到相应对象
            byte[] b = new byte[1024];
            int len;
            while ((len = imageStream.read(b, 0, 1024)) != -1) {
                response.getOutputStream().write(b, 0, len);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @Override
    public InputStream getFlowImgByProcInstId(String procDefId, String procInstId, boolean showHistory) throws Exception {
        InputStream imageStream = null;
        BpmnModel bpmnModel = null;

        List<String> highLightedActivitiIdList = new ArrayList<>();
        List<String> runningActivitiIdList = new ArrayList<>();
        List<String> highLightedFlowIds = new ArrayList<>();

        if (showHistory && StringUtils.isNotEmpty(procInstId)) {
            // 通过流程实例ID获取历史流程实例
            HistoricProcessInstance historicProcessInstance = historyService
                    .createHistoricProcessInstanceQuery()
                    .processInstanceId(procInstId)
                    .singleResult();

            if (null != historicProcessInstance) {

                // 获取流程定义Model对象
                bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());

                //如果需要展示历史节点记录，则需要查询出对应的历史节点信息
                if (showHistory) {
                    // 通过流程实例ID获取流程中已经执行的节点，按照执行先后顺序排序
                    List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
                            .processInstanceId(procInstId)
                            .orderByHistoricActivityInstanceId()
                            .asc().list();

                    // 将已经执行的节点ID放入高亮显示节点集合
                    for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
                        highLightedActivitiIdList.add(historicActivityInstance.getActivityId());
                    }

                    // 通过流程实例ID获取流程中正在执行的节点
                    List<Execution> runningActivityInstanceList = runtimeService.createExecutionQuery().
                            processInstanceId(procInstId).list();
                    for (Execution execution : runningActivityInstanceList) {
                        if (StringUtils.isNotEmpty(execution.getActivityId())) {
                            runningActivitiIdList.add(execution.getActivityId());
                        }
                    }

                    // 获取已流经的流程线，需要高亮显示高亮流程已发生流转的线id集合
                    highLightedFlowIds.addAll(getHighLightedFlows(bpmnModel, historicActivityInstanceList));
                }
            }
        } else if (!showHistory && StringUtils.isNotEmpty(procDefId)) {
            bpmnModel = repositoryService.getBpmnModel(procDefId);
        }


        try {
            if (null != bpmnModel) {
                // 定义流程画布生成器
//                DefaultProcessDiagramGenerator processDiagramGenerator = new DefaultProcessDiagramGenerator();

                // 使用默认配置获得流程图表生成器，并生成追踪图片字符流
//                imageStream = processDiagramGenerator.generateDiagram(
//                        bpmnModel,
//                        "png",
//                        highLightedActivitiIdList,
//                        runningActivitiIdList,
//                        highLightedFlowIds,
//                        "宋体",
//                        "黑体",
//                        "黑体",
//                        null,
//                        2.0);
                /*imageStream = new com.ruoyi.activiti.utils.DefaultProcessDiagramGenerator().generateDiagram(
                        bpmnModel,
                        "png",
                        highLightedActivitiIdList,//所有活动过的节点，包括当前在激活状态下的节点
                        runningActivitiIdList,//当前为激活状态下的节点
                        highLightedFlowIds,//活动过的线
                        "Arial",
                        "Arial",
                        "Arial",
                        null,
                        2.0);*/
                // 定义流程画布生成器
                CustomProcessDiagramGenerator processDiagramGenerator = new CustomProcessDiagramGenerator();
                // 使用默认配置获得流程图表生成器，并生成追踪图片字符流
                imageStream = processDiagramGenerator.generateDiagramCustom(
                        bpmnModel,
                        highLightedActivitiIdList, runningActivitiIdList, highLightedFlowIds, new ArrayList<>(),
                        "宋体", "微软雅黑", "黑体");
            }
            return imageStream;


        } catch (Exception e) {
            log.error("通过流程实例ID[{}]获取流程图时出现异常！", procInstId, e);
            throw new Exception("通过流程实例ID" + procInstId + "获取流程图时出现异常！", e);
        } /*finally {
            if (imageStream != null) {
                try {
                    imageStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }*/
    }

    /**
     * 获取已流经的流程线，需要高亮显示高亮流程已发生流转的线id集合
     *
     * @param bpmnModel
     * @param historicActivityInstanceList
     * @return
     */
    private List<String> getHighLightedFlows(BpmnModel bpmnModel,
                                             List<HistoricActivityInstance> historicActivityInstanceList) {
        // 已流经的流程线，需要高亮显示
        List<String> highLightedFlowIdList = new ArrayList<>();
        // 全部活动节点
        List<FlowNode> allHistoricActivityNodeList = new ArrayList<>();
        // 已完成的历史活动节点
        List<HistoricActivityInstance> finishedActivityInstanceList = new ArrayList<>();

        for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
            // 获取流程节点
            FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance
                    .getActivityId(), true);
            allHistoricActivityNodeList.add(flowNode);
            // 结束时间不为空，当前节点则已经完成
            if (historicActivityInstance.getEndTime() != null) {
                finishedActivityInstanceList.add(historicActivityInstance);
            }
        }

        FlowNode currentFlowNode;
        FlowNode targetFlowNode;
        HistoricActivityInstance currentActivityInstance;
        // 遍历已完成的活动实例，从每个实例的outgoingFlows中找到已执行的
        for (int k = 0; k < finishedActivityInstanceList.size(); k++) {
            currentActivityInstance = finishedActivityInstanceList.get(k);
            // 获得当前活动对应的节点信息及outgoingFlows信息
            currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance
                    .getActivityId(), true);
            // 当前节点的所有流出线
            List<SequenceFlow> outgoingFlowList = currentFlowNode.getOutgoingFlows();

            /**
             * 遍历outgoingFlows并找到已流转的 满足如下条件认为已流转：
             * 1.当前节点是并行网关或兼容网关，则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转
             * 2.当前节点是以上两种类型之外的，通过outgoingFlows查找到的时间最早的流转节点视为有效流转
             * (第2点有问题，有过驳回的，会只绘制驳回的流程线，通过走向下一级的流程线没有高亮显示)
             */
            if ("parallelGateway".equals(currentActivityInstance.getActivityType()) || "inclusiveGateway".equals(
                    currentActivityInstance.getActivityType())) {
                // 遍历历史活动节点，找到匹配流程目标节点的
                for (SequenceFlow outgoingFlow : outgoingFlowList) {
                    // 获取当前节点流程线对应的下级节点
                    targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(outgoingFlow.getTargetRef(),
                            true);
                    // 如果下级节点包含在所有历史节点中，则将当前节点的流出线高亮显示
                    if (allHistoricActivityNodeList.contains(targetFlowNode)) {
                        highLightedFlowIdList.add(outgoingFlow.getId());
                    }
                }
            } else {
                /**
                 * 2、当前节点不是并行网关或兼容网关
                 * 【已解决-问题】如果当前节点有驳回功能，驳回到申请节点，
                 * 则因为申请节点在历史节点中，导致当前节点驳回到申请节点的流程线被高亮显示，但实际并没有进行驳回操作
                 */
                // 当前节点ID
                String currentActivityId = currentActivityInstance.getActivityId();
                int size = historicActivityInstanceList.size();
                boolean ifStartFind = false;
                boolean ifFinded = false;
                HistoricActivityInstance historicActivityInstance;
                // 循环当前节点的所有流出线
                // 循环所有历史节点
                //log.info("【开始】-匹配当前节点-ActivityId=【{}】需要高亮显示的流出线", currentActivityId);
                //log.info("循环历史节点");
                for (int i = 0; i < historicActivityInstanceList.size(); i++) {
                    // // 如果当前节点流程线对应的下级节点在历史节点中，则该条流程线进行高亮显示（【问题】有驳回流程线时，即使没有进行驳回操作，因为申请节点在历史节点中，也会将驳回流程线高亮显示-_-||）
                    // if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
                    // Map<String, Object> map = new HashMap<>();
                    // map.put("highLightedFlowId", sequenceFlow.getId());
                    // map.put("highLightedFlowStartTime", historicActivityInstance.getStartTime().getTime());
                    // tempMapList.add(map);
                    // // highLightedFlowIdList.add(sequenceFlow.getId());
                    // }
                    // 历史节点
                    historicActivityInstance = historicActivityInstanceList.get(i);
                    //log.info("第【{}/{}】个历史节点-ActivityId=[{}]", i + 1, size, historicActivityInstance.getActivityId());
                    // 如果循环历史节点中的id等于当前节点id，从当前历史节点继续先后查找是否有当前节点流程线等于的节点
                    // 历史节点的序号需要大于等于已完成历史节点的序号，防止驳回重审一个节点经过两次是只取第一次的流出线高亮显示，第二次的不显示
                    if (i >= k && historicActivityInstance.getActivityId().equals(currentActivityId)) {
                        //log.info("第[{}]个历史节点和当前节点一致-ActivityId=[{}]", i + 1, historicActivityInstance.getActivityId());
                        ifStartFind = true;
                        // 跳过当前节点继续查找下一个节点
                        continue;
                    }
                    if (ifStartFind) {
                        //log.info("[开始]-循环当前节点-ActivityId=【{}】的所有流出线", currentActivityId);

                        ifFinded = false;
                        for (SequenceFlow sequenceFlow : outgoingFlowList) {
                            // 如果当前节点流程线对应的下级节点在其后面的历史节点中，则该条流程线进行高亮显示
                            // 【问题】
                            //log.info("当前流出线的下级节点=[{}]", sequenceFlow.getTargetRef());
                            if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
                                //log.info("当前节点[{}]需高亮显示的流出线=[{}]", currentActivityId, sequenceFlow.getId());
                                highLightedFlowIdList.add(sequenceFlow.getId());
                                // 暂时默认找到离当前节点最近的下一级节点即退出循环，否则有多条流出线时将全部被高亮显示
                                ifFinded = true;
                                break;
                            }
                        }
                        //log.info("[完成]-循环当前节点-ActivityId=【{}】的所有流出线", currentActivityId);
                    }
                    if (ifFinded) {
                        // 暂时默认找到离当前节点最近的下一级节点即退出历史节点循环，否则有多条流出线时将全部被高亮显示
                        break;
                    }
                }
                //log.info("【完成】-匹配当前节点-ActivityId=【{}】需要高亮显示的流出线", currentActivityId);
            }

        }
        return highLightedFlowIdList;
    }


    /**
     * 根据流程实例Id,获取实时流程图片
     *
     * @param processInstanceId
     * @return
     */
    public  void getFlowImgByInstanceId(String processInstanceId) {
        /*try {
            if (StringUtils.isEmpty(processInstanceId)) {
                logger.error("processInstanceId is null");
                return;
            }
            // 获取历史流程实例
            HistoricProcessInstance historicProcessInstance = activitiUtil.historyService
                    .createHistoricProcessInstanceQuery()
                    .processInstanceId(processInstanceId).singleResult();
            // 获取流程中已经执行的节点，按照执行先后顺序排序
            List<HistoricActivityInstance> historicActivityInstances = activitiUtil.historyService
                    .createHistoricActivityInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .orderByHistoricActivityInstanceId()
                    .asc().list();
            // 高亮已经执行流程节点ID集合
            List<String> highLightedActivitiIds = new ArrayList<>();
            int index = 1;
            for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {

                // 用默认颜色
                highLightedActivitiIds.add(historicActivityInstance.getActivityId());
                index++;
            }
            ProcessDiagramGenerator processDiagramGenerator = null;
            // 使用默认的程序图片生成器
            processDiagramGenerator = new DefaultProcessDiagramGenerator();
            BpmnModel bpmnModel = activitiUtil.repositoryService
                    .getBpmnModel(historicProcessInstance.getProcessDefinitionId());
            // 高亮流程已发生流转的线id集合
            List<String> highLightedFlowIds = getHighLightedFlows(bpmnModel, historicActivityInstances);
            // 使用默认配置获得流程图表生成器，并生成追踪图片字符流
            InputStream imageStream = processDiagramGenerator.generateDiagram(bpmnModel,
                    highLightedActivitiIds, highLightedFlowIds, "宋体",
                    "微软雅黑", "黑体");
            // 输出图片内容
            Integer byteSize = 1024;
            byte[] b = new byte[byteSize];
            int len;
            while ((len = imageStream.read(b, 0, byteSize)) != -1) {
                outputStream.write(b, 0, len);
            }
        } catch (Exception e) {
            logger.error("processInstanceId" + processInstanceId + "生成流程图失败，原因：" + e.getMessage(), e);
        }*/
    }
}
